﻿#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
#endregion

namespace TLib.Xna
{
    public class Camera : GameObject
    {
        //Speed variables
        public float MAX_SPEED = 20f;
        public float ACCEL = 0.75f;
        public float DEACCEL = 0.5f;

        private const float rotationSpeed = 0.1f; //Speed of Camera Rotation

        private float speedF = 0.0f; //Forward
        private float speedB = 0.0f; //Backward
        private float speedL = 0.0f; //Left
        private float speedR = 0.0f; //Right
        private float speedU = 0.0f; //Up
        private float speedD = 0.0f; //Down
        
        private Vector3 reference; //Initial target
        private Vector3 target; //Current target

        private Vector3 moveVector; //Movement of the camera

        public Camera() : base(null)
        {
            Init();
        }

        public void Init()
        {
            pitch = 0;
            yaw = 0;
            roll = 0;

            reference = new Vector3(2.0f, 0.0f, 0.0f);
            target = pos + reference;

            moveVector = Vector3.Zero;
        }

        public Vector3 Reference
        {
            get { return reference; }
            set { reference = value; }
        }

        public Vector3 Target
        {
            get { return target; }
            set { target = value; }
        }

        public Vector3 MoveVector
        {
            get { return moveVector; }
            set { moveVector = value; }
        }

        public override void Update(float delta)
        {
            //Updates the first person camera view matrix

            moveVector.X += (speedF - speedB) * delta;
            moveVector.Y += (speedU - speedD) * delta;
            moveVector.Z += (speedR - speedL) * delta;

            Matrix cameraViewRotationMatrix = Matrix.CreateRotationZ(Pitch) * Matrix.CreateRotationY(Yaw);
            Matrix cameraMoveRotationMatrix = Matrix.CreateRotationY(Yaw);

            Vector3 transformedCameraReference = Vector3.Transform(reference, cameraViewRotationMatrix);

            Position += Vector3.Transform(moveVector, cameraMoveRotationMatrix);

            target = transformedCameraReference + Position;

            //Reset the move vector
            moveVector = Vector3.Zero;

            //Constantly deaccelerate
            if (speedF > 0)
                speedF -= DEACCEL;
            else
                speedF = 0;

            if (speedB > 0)
                speedB -= DEACCEL;
            else
                speedB = 0;

            if (speedL > 0)
                speedL -= DEACCEL;
            else
                speedL = 0;

            if (speedR > 0)
                speedR -= DEACCEL;
            else
                speedR = 0;

            if (speedU > 0)
                speedU -= DEACCEL;
            else
                speedU = 0;

            if (speedD > 0)
                speedD -= DEACCEL;
            else
                speedD = 0;
        }

        public void AccelF()
        {
            if (speedF < MAX_SPEED)
                speedF += ACCEL;
        }

        public void AccelL()
        {
            if (speedL < MAX_SPEED)
                speedL += ACCEL;
        }

        public void AccelR()
        {
            if (speedR < MAX_SPEED)
                speedR += ACCEL;
        }

        public void AccelB()
        {
            if (speedB < MAX_SPEED)
                speedB += ACCEL;
        }

        public void AccelU()
        {
            if (speedU < MAX_SPEED)
                speedU += ACCEL;
        }

        public void AccelD()
        {
            if (speedD < MAX_SPEED)
                speedD += ACCEL;
        }

        public void Rotate(float delta, Vector2 MouseMovementVector)
        {
            Yaw -= MouseMovementVector.X * rotationSpeed * delta;
            Pitch -= MouseMovementVector.Y * rotationSpeed * delta;
        }
    }
}
